/** @file async_task_pool.h
 *
 *  @author Dongryeol Lee (drselee@gmail.com)
 */

#ifndef CORE_PARALLEL_ASYNC_TASK_POOL_H
#define CORE_PARALLEL_ASYNC_TASK_POOL_H

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/thread.hpp>

namespace core {
namespace parallel {

class AsyncTaskPool {
  private:

    /** @brief Asynchronous service for scheduling the tasks.
     */
    boost::asio::io_service svc_;

    /** @brief The running set of threads.
     */
    boost::thread_group threads_;

  public:

    template<typename T>
    void AddTask(T function_in) {
      svc_.post(function_in);
    }

    /** @brief Runs the task pool with a given number of
     *         cores. Assumes that all tasks have been added to the
     *         pool before.
     */
    void Run(int num_cores_in) {

      // Launch threads and run until completion.
      for(int i = 0; i < num_cores_in; i++) {
        threads_.create_thread(
          boost::bind(&boost::asio::io_service::run, &svc_));
      }
      threads_.join_all();
    }
};
}
}

#endif
